package com.googlecode.continuity.plugin.project.server.controller;

import java.util.Date;
import java.util.Map;
import java.text.SimpleDateFormat;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.view.RedirectView;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import com.googlecode.continuity.core.server.mvc.ContinuityModel;
import com.googlecode.continuity.plugin.project.client.Milestone;
import com.googlecode.continuity.plugin.project.client.Project;
import com.googlecode.continuity.plugin.project.server.service.ProjectService;

/**
 * ProjectEditController
 *
 * @author Peter Schmitt <aragos@aragos.de>
 */
public class MilestoneEditController extends SimpleFormController {
// ------------------------------ FIELDS ------------------------------

  private static final String MILESTONE_ATTRIBUTE = "milestone";
  private static final String PROJECT_ATTRIBUTE = "project";

  private ProjectService projectService;
  private String viewURL;
  private String listURL;
  private String addView;
  private String editView;

// --------------------- GETTER / SETTER METHODS ---------------------

  public String getAddView() {
    return addView;
  }

  public void setAddView(String addView) {
    this.addView = addView;
  }

  public String getEditView() {
    return editView;
  }

  public void setEditView(String editView) {
    this.editView = editView;
  }

  public String getListURL() {
    return listURL;
  }

  public void setListURL(String listURL) {
    this.listURL = listURL;
  }

  public String getViewURL() {
    return viewURL;
  }

  public void setViewURL(String viewURL) {
    this.viewURL = viewURL;
  }

  public void setProjectService(ProjectService projectService) {
    this.projectService = projectService;
  }

// -------------------------- OTHER METHODS --------------------------

  protected Object formBackingObject(HttpServletRequest request) throws Exception {
    return request.getAttribute(MILESTONE_ATTRIBUTE);
  }

  protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
      throws Exception {
    if (isAddRequest(request)) {
      int projectID = Integer.parseInt(request.getParameter("project"));
        Project project = projectService.getProjectByID(projectID);

        // if project doesn't exist show error and go to list of projects
        // todo: include error
        if (project == null) {
          return new ModelAndView(new RedirectView(getListURL(), true));
        }
      request.setAttribute(PROJECT_ATTRIBUTE, project);
    }

    if (!isFormSubmission(request)) {
      if (isAddRequest(request)) {
        request.setAttribute(MILESTONE_ATTRIBUTE, new Milestone());
      } else {
        int milestoneID = Integer.parseInt(request.getParameter("id"));
        Milestone milestone = projectService.getMilestoneByID(milestoneID);

        // if milestone doesn't exist show error and go to list of projects
        // todo: include error
        if (milestone == null) {
          return new ModelAndView(new RedirectView(getListURL(), true));
        }
        request.setAttribute(MILESTONE_ATTRIBUTE, milestone);
      }
    }

    return super.handleRequestInternal(request, response);
  }

  protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object o,
                                  BindException errors) throws Exception {
    Milestone milestone = (Milestone) o;
    if (isAddRequest(request)) {
      int projectID = Integer.parseInt(request.getParameter("project"));
      Project project = projectService.getProjectByID(projectID);

      // if project doesn't exist show error and go to list of projects
      // todo: include error
      if (project == null) {
        return new ModelAndView(new RedirectView(getListURL(), true));
      }

      project.addMilestone(milestone);
      projectService.storeProject(project);
    } else {
      projectService.storeMilestone(milestone);
    }
    return new ModelAndView(new RedirectView(getViewURL(), true), "id", milestone.getId());
  }

  protected ModelAndView showForm(HttpServletRequest request, HttpServletResponse response, BindException errors,
                                  Map controlModel) throws Exception {
    ContinuityModel model = new ContinuityModel();
    Project project = (Project) request.getAttribute(PROJECT_ATTRIBUTE);
    if (project != null) {
      model.put("project", project);
    }
    String view = getEditView();
    if (isAddRequest(request)) {
      view = getAddView();
    }
    return showForm(request, errors, view, model);
  }

  private boolean isAddRequest(HttpServletRequest request) {
    return request.getRequestURI().contains("add");
  }

  protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder)
      throws Exception {
    // todo: config!
    binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("dd.MM.yy HH:mm"), true));
  }
}